var XT = XT || {
    config: {
        yybUrl: 'https://a.app.qq.com/o/simple.jsp?pkgname=com.shijia.baimei&android_scheme='
    },
    interface: {
        __chance: function  (prefix,url) {
            var host = window.location.hostname;
            var newHost = '';
            var prefix = prefix || 'api';
            switch(true) {
                case /h5-t/g.test(host):
                    newHost = 'https://'+prefix+'-t.chinaqljf.com';
                    break;

                case /dev/g.test(host):
                    newHost = 'https://'+prefix+'-dev.chinaqljf.com';
                    break;

                case /h5-a/g.test(host):
                    newHost = 'https://'+prefix+'-a.chinaqljf.com';
                    break;

                case /localhost/g.test(host):
                    newHost = 'https://'+prefix+'-t.chinaqljf.com';
                    break;
                case /file/g.test(host):
                    newHost = 'https://'+prefix+'-t.chinaqljf.com';
                    break;

                default:
                    if(prefix == 'bmshop') {
                        newHost = 'https://ashop.baimeitv.com';
                    }else {
                        newHost = 'https://'+prefix+'.chinaqljf.com';
                    }
                    break;
            }

            return newHost+url;
        },
        api: function  (url) {
            return this.__chance('api',url);
        },
        fun: function  (url) {
            return this.__chance('fun',url);
        },
        pay: function  (url) {
            return this.__chance('pay',url);
        },
        chat: function (url) {
            return this.__chance('chat',url);
        },
        shop: function  (url) {
            return this.__chance('bmshop',url);
        },
        open: function(url) {
            return this.__chance('open-api', url);
        }
    },
    /**
     * URL参数
     * @type {Object}
     */
    search: JSON.parse('{' + (location.search.match(/[\w\%]+=[^\&\=]+/g) || []).map(function(value) {
        return '"' + value + '"'
    }).join(',').replace(/=/g, '":"') + '}'),

    /**
     * ua
     * @type {Object}
     */
    ua: {
        isApp: /bmlive/i.test(navigator.userAgent),
        isWeixin: /MicroMessenger/i.test(navigator.userAgent),
        isIos: /iphone|ipad/i.test(navigator.userAgent),
        isAndroid: /android/i.test(navigator.userAgent),
        isMobile: /iphone|ipad|android|mobile/i.test(navigator.userAgent),
        isUC: /UCWEB|UCBrowser/i.test(navigator.userAgent)
    },

    /**
     * 用户信息
     * @type {Object}
     */
    user: {
        default_avatar: '',
        uid: '',
        token: ''
    },

    /**
     * 获取seqId函数
     * @return {String}
     */
    getSeqId: function() {
        return new Date(Date.now() + 8 * 60 * 60 * 1000).toISOString().replace(/\D/g, '').substr(0, 14) + ('' + (1 + Math.random()) * 1e7).substr(1, 6);
    },

    /**
     * 协议跳转
     * @param  {String} bmlive协议, 缺省值是app首页
     * @param  {String} 不支持bmlive协议环境的降级url, 缺省值是下载app页面
     * @return {Void} 
     */
    go: function(scheme, url) {
        if (XT.ua.isApp) {
            window.location.href = scheme || 'bmlive://home?id=0';
        } else {
            if (!(document.hidden || document.webkitHidden)) {
                window.location.href = url || 'https://www.chinaqljf.com/';
            }
        }
    },

    /**
     * 加载静态资源
     * @param  {Object} 加载静态资源的对应参数，包括 js、css、jsVer、cssVer、allVer
     *                  {array} js、css
     *                  {string} jsVer、cssVer、allVer
     */
    load: function(obj) {
        var resources = {
            css: obj.css || '',
            js: obj.js || ''
        }
        var version = {
            css: obj.cssVer || obj.allVer || +(new Date),
            js: obj.jsVer || obj.allVer || +(new Date)
        }
        for (var key in resources) {
            for (var i = 0; i < resources[key].length; i++) {
                loadjscssfile(resources[key][i] + '?' + version[key], key)
            }
        }

        function loadjscssfile(filename, filetype) {
            if (filetype == "js") {
                var fileref = document.createElement('script');
                fileref.setAttribute("type", "text/javascript");
                fileref.setAttribute("src", filename);
            } else if (filetype == "css") {

                var fileref = document.createElement('link');
                fileref.setAttribute("rel", "stylesheet");
                fileref.setAttribute("type", "text/css");
                fileref.setAttribute("href", filename);
            }
            if (typeof fileref != "undefined") {
                document.getElementsByTagName("head")[0].appendChild(fileref);
            }

        }
    },

    /**
     * 频率控制 返回函数连续调用时，func 执行频率限定为 次 / wait
     * @param func
     * @param wait
     * @param options
     * @returns {Function}
     */
    throttle : function(func, wait, options) {
        var context, args, result;
        var timeout = null;
        // 上次执行时间点
        var previous = 0;
        if (!options) options = {};
        // 延迟执行函数
        var later = function() {
            // 若设定了开始边界不执行选项，上次执行时间始终为0
            previous = options.leading === false ? 0 : Date.now();
            timeout = null;
            result = func.apply(context, args);
            if (!timeout) context = args = null;
        };
        return function() {
            var now = Date.now();
            // 首次执行时，如果设定了开始边界不执行选项，将上次执行时间设定为当前时间。
            if (!previous && options.leading === false) previous = now;
            // 延迟执行时间间隔
            var remaining = wait - (now - previous);
            context = this;
            args = arguments;
            // 延迟时间间隔remaining小于等于0，表示上次执行至此所间隔时间已经超过一个时间窗口
            // remaining大于时间窗口wait，表示客户端系统时间被调整过
            if (remaining <= 0 || remaining > wait) {
                clearTimeout(timeout);
                timeout = null;
                previous = now;
                result = func.apply(context, args);
                if (!timeout) context = args = null;
                //如果延迟执行不存在，且没有设定结尾边界不执行选项
            } else if (!timeout && options.trailing !== false) {
                timeout = setTimeout(later, remaining);
            }
            return result;
        };
    },

    /**
     * 空闲控制 返回函数连续调用时，空闲时间必须大于或等于 wait，func 才会执行
     *
     * @param  {function} func        传入函数
     * @param  {number}   wait        表示时间窗口的间隔
     * @param  {boolean}  immediate   设置为ture时，调用触发于开始边界而不是结束边界
     * @return {function}             返回客户调用函数
     */
    debounce : function(func, wait, immediate) {
        var timeout, args, context, timestamp, result;

        var later = function() {
            // 据上一次触发时间间隔
            var last = Date.now() - timestamp;

            // 上次被包装函数被调用时间间隔last小于设定时间间隔wait
            if (last < wait && last > 0) {
                timeout = setTimeout(later, wait - last);
            } else {
                timeout = null;
                // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
                if (!immediate) {
                    result = func.apply(context, args);
                    if (!timeout) context = args = null;
                }
            }
        };

        return function() {
            context = this;
            args = arguments;
            timestamp = Date.now();
            var callNow = immediate && !timeout;
            // 如果延时不存在，重新设定延时
            if (!timeout) timeout = setTimeout(later, wait);
            if (callNow) {
                result = func.apply(context, args);
                context = args = null;
            }

            return result;
        };
    },

    /**
     * 封装的jsonp
     * XT.jsonp({
     *     url  : 'http://...', //接口url
     *     data : {},           //[可选]请求数据
     *     jsonpCallback : '',  //[可选]回调的函数名
     *     super_success : function(res){}, //[可选]直接处理jsonp返回原始数据的函数
     *     success : function (data) {},    //[可选]在没有super_success下, 处理code=0时的data数据
     *     fail    : function(){}           //[可选]错误的处理函数
     *     validMsg:function(){}            //[可选]校验失败的message函数 add by 刘涛 2016-07-26
     * })
     */
    jsonp: function(obj) {
        if (!obj.url) return;
        var name = obj.url.split('/').slice(3).join('/');
        var $deferred = jQuery.ajax({
            //如果传进来的是http请求的url则直接使用该url,否则带上前缀 update by 刘涛 2016-07-25
            url: /http/g.test(obj.url) ? obj.url : XT.interface.api(obj.url),
            dataType: 'jsonp',
            data: jQuery.extend({
                M: 'H5'
            }, obj.data),
            jsonpCallback: obj.jsonpCallback,
            success: function(res) {
                if (typeof obj.super_success === 'function') {
                    obj.super_success(res);
                } else {
                    if (res.code == 'ok') {
                        console.log(name, res);
                        if (typeof obj.success === 'function') {
                            obj.success(res.data);
                        }
                    } else {
                         console.log('[' + res.code + ']' + res.message, name, res);
                        //当有业务校验返回时需要提醒校验失败信息,将信息展示至界面 update by 刘涛 2016-07-26
                         if (typeof obj.validMsg === 'function') {
                             obj.validMsg(res.message);
                         } 
                    }
                }
            }
        });
        return $deferred;
    },
    /*obj对象元素type Number 转String */
    numToStr: function(obj){
        if(!obj)return;
        for(var attr in obj){
            if($.isNumeric(obj[attr])){
                obj[attr] += '';
            }
        }
    },
    signJsonp: function(obj) {
        if (!obj.url) return;

        /*针对ios data传Number闪退问题*/
        XT.numToStr(obj.data);

        // XT.jsonp(obj);

        XT.sign('GET', obj.data, function(signRes) {
              var _tmp = $.extend({sign:signRes.sign}, signRes.parameters);
              var secureStr = XT.urlEncode(_tmp).substr(1);
              obj.url += '?' + secureStr;
              XT.jsonp(obj);
        })
    },
    /*
     * 封装的get
     * XT.get({
     *     url  : 'http://...', //接口url
     *     data : {},           //[可选]请求数据
     *     super_success : function(res){}, //[可选]直接处理post返回原始数据的函数
     *     success : function (data) {},    //[可选]在没有super_success下, 处理code=0时的data数据
     *     fail    : function(){}           //[可选]错误的处理函数
     * })
     */
    get: function(obj, requestType) {
      if (!obj.url) return;
        var data = jQuery.extend({
            M: 'H5'
        }, obj.data);


        if(requestType && requestType.toLowerCase() == 'post'){
            data = JSON.stringify(data);
        }

        jQuery.ajax({
            //如果传进来的是http请求的url则直接使用该url,否则带上前缀 update by 刘涛 2016-07-25
            url: /http/g.test(obj.url) ? obj.url : XT.interface.api(obj.url),
            type: requestType || 'GET',
            // 将XHR对象的withCredentials设为true
            //crossDomain: true,
            xhrFields:{
                withCredentials:true
            },
            dataType: 'json',
            data: data,
            headers: {
              "Authorization": XT.tools.getStorage('token')
            },
            contentType: 'application/json',
            success: function(res) {
                if (typeof obj.super_success === 'function') {
                    obj.super_success(res);
                } else {
                    if (res.code == 'ok') {
                        // console.log(name, res);
                        if (typeof obj.success === 'function') {
                            obj.success(res.data);
                        }
                    } else {
                        // console.log('[' + res.code + ']' + res.message, name, res);
                        //当有业务校验返回时需要提醒校验失败信息,将信息展示至界面 update by 刘涛 2016-07-26
                        if (typeof obj.validMsg === 'function') {
                            obj.validMsg(res.message);
                        }
                    }
                }
            },
            error: function(data) {
                if (typeof obj.fail === 'function') {
                    obj.fail(data);
                } else if(typeof obj.error === 'function'){
                    obj.error(data);
                }else{
                    console.log('网络错误', name);
                }
            }
        });
    }, 
    /*针对ajax token失败的时候做微信登录处理,因不能得到失败状态,因此只要执行error方法默认就会跳转,当error返回true时不跳转*/
    ajaxRequest: function(obj, type){
        var erroFn = obj.erroFn || $.noop;
        obj.error = function(){
            if(erroFn.call(window, arguments) !== true){
                XT.requestWXLogin();
            }
        };
        this.get(obj, type);
    },
    /**
     * 封装的post
     * XT.post({
     *     url  : 'http://...', //接口url
     *     data : {},           //[可选]请求数据
     *     super_success : function(res){}, //[可选]直接处理post返回原始数据的函数
     *     success : function (data) {},    //[可选]在没有super_success下, 处理code=0时的data数据
     *     fail    : function(){}           //[可选]错误的处理函数
     * })
     */
    post: function(obj) {
      if (!obj.url) return;
      // var name = obj.url.split('/').slice(3).join('/');
      XT.sign('POST', obj.data, function(signRes) {
          var _tmp = $.extend({sign:signRes.sign}, signRes.parameters);
          var secureStr = XT.urlEncode(_tmp).substr(1);
          obj.url += '?' + secureStr;

          jQuery.ajax({
              //如果传进来的是http请求的url则直接使用该url,否则带上前缀 update by 刘涛 2016-07-25
              url: /http/g.test(obj.url) ? obj.url : XT.interface.api(obj.url),
              type: 'POST',
              // 将XHR对象的withCredentials设为true
              crossDomain: true,
              xhrFields:{
                  withCredentials:true
              },
              data: signRes.body,
              contentType: obj.contentType || 'application/json',
              success: function(res) {
                  if (typeof obj.super_success === 'function') {
                      obj.super_success(res);
                  } else {
                      if (res.code == 'ok') {
                          // console.log(name, res);
                          if (typeof obj.success === 'function') {
                              obj.success(res.data);
                          }
                      } else {
                          // console.log('[' + res.code + ']' + res.message, name, res);
                          //当有业务校验返回时需要提醒校验失败信息,将信息展示至界面 update by 刘涛 2016-07-26
                          if (typeof obj.validMsg === 'function') {
                              obj.validMsg(res.message);
                          }
                      }
                  }
              },
              error: function(data) {
                  if (typeof obj.fail === 'function') {
                      obj.fail(data);
                  } else if(typeof obj.error === 'function'){
                      obj.error(data);
                  }else{
                      console.log('网络错误', name);
                  }
              }
          });

      });


    },
    sign: function(method, args, cb){
        args = $.extend({
            M: 'H5'
        }, args);
        XT.bridge.call('getApiSign', {
            method: method,
            parameters: args
        }, function(res) {
         /* res参数为js-bridge回调的参数，其数据结构：
          * {
          *   "parameters": {},  //公共参数
          *   "body": "",  // 业务参数
          *   "sign": "",  // 签名
          * }
          */
            var b = JSON.parse(res);
            cb && cb(b);
        });
    }
};

/**
 * 分享
 * @type {Object}
 * XT.share.set 设置分享
 * XT.share.pop 弹出分享弹窗
 */
XT.share = (function() {
    var _config = {
        title: document.title, // 分享标题
        desc: document.title || '百媚直播', // 分享描述
        imgUrl: 'https://h5.chinaqljf.com/base/images/icon-app.png', //分享图标
        url: location.origin + location.pathname + (location.search || '?H5'), //分享链接
        link: location.origin + location.pathname + (location.search || '?H5'),
        type: '', // 分享类型,music、video或link，不填默认为link
        dataUrl: '', // 如果type是music或video，则要提供数据链接，默认为空
        success: function() {}, // 用户分享成功后执行的回调函数
        cancel: function() {} // 用户取消分享后执行的回调函数
    }

    var _popWeixinShare = $('<div id="pop-weixin-share" class="g-wx-share-mask"></div>');
    $(function() {
        _popWeixinShare.on('click', function() {
            $(this).removeClass('on');
        }).appendTo('body');
    });

    var _share = {
        wxConfig: {
            debug: false,
            jsApiList: [
                'onMenuShareAppMessage',
                'onMenuShareTimeline',
                'onMenuShareWeibo',
                'onMenuShareQQ',
                'chooseWXPay'
            ]
        },
        wxIsReady: false,
        wx: window.wx,
        set: function(data) {
            _config = $.extend(_config, data);
            _setWeixinShare();
            console.log('[share]', _config);
        },
        pop: function(data) {
            if (data) this.set(data);

            switch (true) {

                case XT.ua.isWeixin:
                    _popWeixinShare.addClass('on');
                    break;

                default:
                    console.log('触发分享');
            }
        }
    }


    //设置微信分享信息
    var _setWeixinShare = function() {
        if (window.wx && _share.wxIsReady) {
            window.wx.onMenuShareAppMessage(_config);
            window.wx.onMenuShareTimeline(_config);
            window.wx.onMenuShareWeibo(_config);
            window.wx.onMenuShareQQ(_config);
        }
    }

    //获取微信分享配置信息
    if (window.wx) {
        $.ajax({
            url: XT.interface.api('/share/config/wx-web-auth?url=' + encodeURIComponent(location.href.replace(/#.*$/, ''))),
            dataType: 'jsonp',
            success: function(res) {
                if (res.code == "ok") {
                    XT.share.wxConfig = $.extend(res.data, XT.share.wxConfig);
                    XT.share.wxConfig.timestamp=res.data.timeStamp;
                    window.wx.config(XT.share.wxConfig);
                    window.wx.ready(function() {
                        _share.wxIsReady = true;
                        _setWeixinShare();
                    });
                }
            }
        });
    }

    return _share;
})()

/**
 * app的bridge对象
 * @type {Object}
 */
XT.bridge = (function() {

    var _bridge = {
        /**
         * app的bridge对象是否加载好
         * @type {Boolean}
         */
        isReady: false,

        queue: {
            call:[],
            on:[]
        },

        /**
         * 侦听bridge事件
         * @param  {String}   event    事件名
         * @param  {Function} callback 回调函数
         * @return {Object}            XT.bridge
         */
        on: function(event, callback) {
            if(!event) return this;
            if(typeof callback !== 'function') callback = function () {};
            if (_bridge.origin) {
                _bridge.origin.registerHandler(event, callback);
            }
            else {
                _bridge.queue.on.push({
                    event: event,
                    callback: callback
                });
            }
            return this;
        },

        /**
         * 触发bridge事件处理器
         * @param  {String}   event    事件名
         * @param  {Object}   data     数据
         * @param  {Function} callback 回调函数
         * @return {Object}            XT.bridge
         */
        call: function(event, data, callback) {
            if(!event) return this;
            if (_bridge.origin) {
                _bridge.origin.callHandler(event, data, callback);
            }
            else {
                _bridge.queue.call.push({
                    event: event,
                    data: data,
                    callback: callback
                });
            }
            return this;
        },

        /**
         * bridge的debug, 手动设置uid和token
         * @param  {Object} data 数据
         * @return {Object}      XT.bridge
         */
        debug: function(data) {
            if (!XT.ua.isApp) {
                XT.user.uid = data.uid;
                XT.user.token = data.token;
            }
            return this;
        },

        /**
         * 登录弹窗
         * @param  {Function} callback 回调
         * @return {Object}            XT.bridge
         */
        login: function(callback) {
            _bridge.call('login', {}, callback);
            return this;
        }
    };

    //设置用户信息
    var _setUserInfo = function(res) {
        res = res ? JSON.parse(res) : {};

        XT.user = $.extend(XT.user, res);

    }

    //初始化
    _bridge.ready = function(bridgeOjbect, event) {
        if (_bridge.isReady) return;
        _bridge.isReady = true;

        //原始bridge对象存放到origin
        _bridge.origin = bridgeOjbect;

        //注册监听
        try {
            _bridge.origin.init(function(message, responseCallback) {});
        }
        catch(e){
        }
        setTimeout(function  () {
            //获取登录用户的信息
            _bridge.call('getUserInfo', {}, function(res) {
                _setUserInfo(res)
            });

            // 设置原生分享按钮
            if(XT.search.extCode) {
                _bridge.call('getUserInfo', {}, function(res) {
                    var info = JSON.parse(res||{});

                    XT.jsonp({
                        url: '/share/share-getByExtCode?extCode='+XT.search.extCode+'&shareUserId='+info.id,
                        jsonpCallback: '_nativeShare',
                        success: function (data) {
                            XT.bridge.call('setShareInfo', {
                                id: String(data.id),
                                type: XT.search.extShareType || 'page'
                            }, function(res) {
                                var b = JSON.parse(res);
                                console.log('setShareInfo result:'+b);
                            });
                        }
                    });
                });
            }
            else if(XT.search.shareType &&　XT.search.shareId) {
                _bridge.call('setShareInfo', {
                    type: XT.search.shareType,
                    id: XT.search.shareId
                }, function(res) {
                    var b = JSON.parse(res);

                    if(b) {
                        $(".u-page-share-btn").remove();
                    }
                });
            }
        },0)
        _bridge.queue.on.forEach(function (item) {
            try {
                _bridge.origin.registerHandler(item.event, item.callback);
            }
            catch(e){
            }
        })

        _bridge.queue.call.forEach(function (item) {
            try {
                _bridge.origin.callHandler(item.event, item.data, item.callback);
            }
            catch(e){
            }
        })
    };

    //bridge创建监听
    function setupWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) {
            return callback(WebViewJavascriptBridge);
        } else {
            document.addEventListener('WebViewJavascriptBridgeReady', function() {
                callback(WebViewJavascriptBridge);
            }, false);
        }
        if (window.WVJBCallbacks) {
            return window.WVJBCallbacks.push(callback);
        }
        window.WVJBCallbacks = [callback];

        var WVJBIframe = document.createElement('iframe');
        WVJBIframe.style.display = 'none';
        WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
        document.documentElement.appendChild(WVJBIframe);
        setTimeout(function() {
            document.documentElement.removeChild(WVJBIframe)
        }, 0);
    }

    setupWebViewJavascriptBridge(_bridge.ready);

    return _bridge;
})()
XT.setShare = function() {
    var tpl = '';

    if (!XT.ua.isApp) {
        tpl = '<aside class="g-download-guide">' +
            '<a href="https://a.app.qq.com/o/simple.jsp?pkgname=com.shijia.baimei&android_scheme=bmlive%3A%2F%2Fbmlive%2Fhome%3Fid%3D0" class="u-download-btn">立即下载</a>' +
            '<figure class="m-app-info">' +
            '<img src="../base/images/icon-app.png" alt="" class="logo">' +
            '<figcaption class="info">' +
            '<h1 class="name">百媚直播</h1>' +
            // '<p class="intro">聚星闪耀 与众不瞳</p>' +
            '</figcaption>' +
            '</figure>' +
            '</aside>';

        // $('body').prepend(tpl);
    }
}

//根据实际尺寸获取图片地址
XT.getImgUrl = function(url, w, h){
    if(!w && !h)return url;
    if(!/chinaqljf/g.test(url))return url;
    var _url = url;    
    var _extension = _url.substring(_url.lastIndexOf('.') + 1);
    if(/cdn/g.test(_url)){
        if(w){
            _url += '@' + w + 'w';
        }
        if(h){
            if(w){            
                _url += '_' + h + 'h';
            }else{
                _url += '@' + h + 'h';
            }
        }
        _url + '.' + _extension;
    }else{
        _url += '?x-oss-process=image/resize';
        if(w){
            _url += ',w_' + w;
        }
        if(h){
            _url += ',h_' + h;
        }
    }    
    return _url;
};

XT.urlEncode = function (param, key, encode) {
    if(param==null) return '';
    var paramStr = '';
    var t = typeof (param);
    if (t == 'string' || t == 'number' || t == 'boolean') {
        paramStr += '&' + key + '=' + ((encode==null||encode) ? encodeURIComponent(param) : param);
    } else {
        for (var i in param) {
            var k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i);
            paramStr += XT.urlEncode(param[i], k, encode);
        }
    }
    return paramStr;
};



/*客户端工具函数*/
XT.tools = {
    /**
     * 存储cookie
     * @param {[String]} name    [cookie名称]
     * @param {[String]} value   [cookie的值]
     * @param {[Number]} expires [过期时间,单位为秒,默认为当前会话]
     * @param {[String]} path    [保存路径,默认为'/']
     */
    setCookie: function(name, value, expires, path){
        var oDate = new Date();
        oDate.setTime(oDate.getTime() + (expires*1000 || 0));
        document.cookie = name + '=' + encodeURIComponent(value) + '; path='+ (path || '/')+'; expires=' + (expires ? oDate.toUTCString() : '');
    },
    /**
     * [getCookie 获取cookie]
     * @param  {[String]} name [要获取cookie的名称]
     * @return {[String]}      [返回cookie值, 否则返回null]
     */
    getCookie: function(name){
        var cookies = document.cookie ? document.cookie.split('; ') : [];
        for(var i = 0; i < cookies.length; i++){
            var ret = cookies[i].split('=');
            if(ret[0] == name){
                return decodeURIComponent(ret[1]);
            }
        }
        return null;
    },
    removeCookie: function(name){
        this.setCookie(name, null, -1);
    },
    /**
     * [setStorage 设置本地存储,如果不支持则采用cookie方式存储1年]
     * @param {[String]} name  [名称]
     * @param {[String]} value [值]
     */
    setStorage: function(name, value){
        if(window.localStorage){
            window.localStorage.setItem(name, value);
        }else{
            return this.setCookie(name, value, 365*24*3600);
        }
    },
    /**
     * [getStorage 获取本地存储,如果不支持则从cookie中取]
     * @param  {[String]} name [名称]
     * @return {[String]}      [值]
     */
    getStorage: function(name){
        if(window.localStorage){
            return window.localStorage.getItem(name);
        }else{
            return this.getCookie(name);
        }
    },
    removeStorage: function(name){
        if(window.localStorage){
            if(name == 'all'){
                window.localStorage.clear();
            }else{
                window.localStorage.removeItem(name);
            }
        }else{
            this.removeCookie(name);
        }
    },
    /**
     * [sessionStorage 存储]
     * @param  {[type]} value [value===null时为清除]
     */
    session: function (key, value){
        if(window.sessionStorage){
            if(arguments.length == 2){
                if(value === null){
                    window.sessionStorage.removeItem(key);
                }else{
                    window.sessionStorage.setItem(key, value);
                }
            }else{
                return window.sessionStorage.getItem(key);
            }
        }else{
            if(arguments.length == 2){
                if(value === null){
                    this.removeCookie(key);
                }else{
                    this.setCookie(key, value);
                }
            }else{
                return this.getCookie(key);
            }
        }
    },
    /**
     * [fillZero 数字前面补零]
     * @param  {[Number]} num [要补零的数字]
     * @param  {[Number]} n   [补零后的位数, 默认值为2]
     * @return {[String]}     [返回补零后的结果]
     * fillZero(6, 2) => '06';
     */
    fillZero: function(num, n){
        n = n || 2;
        return (new Array(n+1).join(0)+String(num)).substr(-n);
    }
};



/**
 * [debug 调试打印, 更多便于手机端, 支持打印对象]
 * @param  {[Arg]} content  [要打印的内容]
 * @param  {[Boolean]} status  [默认为true。 window.DEBUG为false的时候关闭可将此设置为true打印]
*/
XT.debug = function (content, status){
    var $debug = jQuery('#j-debug');

    status  = typeof status === 'undefined' ? (typeof window.DEBUG === 'undefined' ? true : window.DEBUG): status;
    content = format(content);

    function format(content){
        return jQuery.isPlainObject(content) ? JSON.stringify(content, 2, 4) : content;
    }

    function formatArr(arr){
        return arr.map(function(item){
            return jQuery.isArray(item) ? '[' + formatArr(item) + ']' : format(item);
        });
    }

    content = jQuery.isArray(content) ? '[' + formatArr(content) + ']' : content;

    if($debug.size() == 0){
        $debug = jQuery('<ol id="j-debug" style="position:relative;z-index:50;font-size:0.3rem;clear:both;line-height:1.5;padding:0 5%;border-top:2px solid #6ce26c;background:#eee;"></ol>').appendTo(jQuery('body'));
    }

    if(status){
        $debug.append('<li style="list-style:decimal;list-style-position:outside;padding:0 2%;border-left: 1px solid #6ce26c;"><pre>'+ content +'</pre></li>');
    }

    if($debug.children().size() < 1){
        $debug.remove();
    }
};


/**
 * [message 信息提示框]
 * @param  两个参数的时候, 第一个代表为message 要弹出的元素, 支持传入jQuery对象或jQuery选择器,
 *                        第二个参数为提示信息或options对象, 不传入则从 message 对象中取innerHTML。
 *         一个参数的时候, 如果传入的是Object对象, 参考config默认对象。 如果传入的是字符串, 则表示要提示的文字信息。
 * @example:
 * $.message('hello world!')
 * $.message({content: 'hello world!', backdrop: false})
 * $.message('div.message', 'hello world!')
 * $.message('div.message', {duration: 100})
 */
XT.message = function(){
    var config = {
        opened: $.noop,
        closed: $.noop,
        willOpen: $.noop,
        willClose: $.noop,
        content: '',
        duration: 0,
        delay: 3000,
        backdrop: true,
        addClassName: '',
        style: {},
        effect: 'fadeToOut'
    },
    $message = null,
    arg      = arguments,
    options  = arg[0];

    if(arg.length == 2){
        $message = jQuery(options);
        config.content = $message.html();

        if(arg[1]){
            $.isPlainObject(arg[1]) ? $.extend(config, arg[1]) : config.content = arg[1];
        }
    }else{
        $message = $('<div class="xt-message"></div>').appendTo('body');
        typeof options === 'string' ? config.content = options : $.extend(config, options);
    }

    config.willOpen.call($message[0]);
    config.backdrop && (config.addClassName += ' backdrop');
    $message.css(config.style).addClass(config.addClassName).html(config.content).fadeIn(config.duration, function(){
      $(this).addClass(config.effect);
    });

    var $cnt = $message.wrapInner('<div class="xt-message-cnt"></div>').find('.xt-message-cnt');
    var iWidth = $cnt.outerWidth();
    $cnt.css({
        width: iWidth,
        left: '50%',
        top: '50%',
        marginLeft: -iWidth/2,
        marginTop: -$cnt.outerHeight()/2
    });

    $message.timer = setTimeout(function(){
        $message.removeClass(config.effect);
        config.willClose.call($message[0]);
        $message.fadeOut(config.duration, function(){
            clearTimeout($message.timer);
            config.closed.call(this);
            arg.length === 1 ? $message.remove() : $message.html($cnt.html());
        });
    }, config.delay);
};



/**
 * [getUserInfo 获取用户信息, 通过bridge调用底层方法'getUserInfo', 成功后会赋值XT.search.userId]
 * @param  {Function} callback [获取成功后的回调函数]
 * @param  {[Object]} params   [获取传递的参数对象]
 */
XT.getUserInfo = function(callback, params){
    var self   = this;
        params = params || {};
    if(XT.search.userId) {
        callback && callback({id: XT.search.userId})
    }else {
        XT.bridge.call('getUserInfo', params, function (res){
            if(!self.userId){
                var info = JSON.parse(res);
                XT.search.userId = self.userId = info.id;
                callback && callback(info);
            }
            clearTimeout(self.timer);
        });

        this.timer = setTimeout(function(){
            if(!self.userId){
                XT.getUserInfo(callback, params);
            }
        }, 100);
    }
};

//用户等级判断
XT.getUserLevel = function(level){
    var res = 1;
    if ( level > 10 && level <= 15 ){
         res = 2;
    }else if ( level > 15 && level <= 20 ){
         res = 3;
    }else if ( level > 20 && level <= 25 ){
         res = 4;
    }else if ( level > 25 && level <= 30 ){
         res = 5;
    }else if ( level > 30 && level <= 35 ){
         res = 6;
    }else if ( level > 35 && level <= 45 ){
         res = 7;
    }else if ( level > 45 && level <= 55 ){
         res = 8;
    }else if ( level > 55 ){
         res = 9;
    }
    return res;
}


/*
  微信登录 XT.requestWXLogin();
*/
XT.requestWXLogin = function(options){
    if(!XT.ua.isWeixin)return;
    var _data  = $.extend({inviteCode: 88888}, XT.search);
        delete _data.code;
        delete _data.state;

    var _wxconfig = $.extend(true, {
        data: _data,
        url: XT.interface.api('/auth/h5/login-by-wx'),
    }, options||{});


    //if(!window.weixinUtil.hasAuthorized() && !XT.search['test']) {
    if(!XT.search['test']) {
        XT.tools.setStorage('_wxconfig', JSON.stringify(_wxconfig));
        window.weixinUtil.authorize();
        return;
    }
}

/*微信登录后初始化页面*/
XT.wxloginCompleted = function(cb, options){
    var _wxconfig = XT.tools.getStorage('_wxconfig');
    var data = {
        userId: XT.tools.getStorage('userId'),
        userInfo: JSON.parse(XT.tools.getStorage('userInfo') || '{}'),
        appKey: XT.tools.getStorage('appKey'),
        imToken: XT.tools.getStorage('imToken'),
        token: XT.tools.getStorage('token'),
        imAccountId: XT.tools.getStorage('imAccountId'),
        openId: XT.tools.getStorage('openId'),
    };

    if(_wxconfig){
        _wxconfig = JSON.parse(_wxconfig);

        if(!_wxconfig){
            cb && cb(data);
        }else{
            var $msg = $('<div class="err-msg" style="display:none">网络异常, 请<a href="javascript:;">重新加载</a></div>').appendTo('body');
            
            $.extend(true, _wxconfig.data,  XT.search);

            _wxconfig.super_success = function(data){
                if(options && options.super_success){
                    options.super_success(data);
                }

                if(data.code != 'ok') {
                    if(data.code == 'CF0404') { //code已经被使用
                        var authNum = parseInt(XT.tools.getStorage('authNum'));
                        if(authNum < 2 || !authNum){
                            XT.requestWXLogin();
                        }
                    }else{
                        $msg.show().click(function(){
                            XT.requestWXLogin();
                        })
                    }
                }else{
                    if(_wxconfig.success){
                        _wxconfig.success(data.data);
                    }
                }
            };

            _wxconfig.success = function(res){
                XT.tools.removeStorage('_wxconfig');
                
                if(res && res.userInfo){
                    XT.tools.setStorage('userInfo', JSON.stringify(res.userInfo));
                    XT.tools.setStorage('userId', res.userInfo.id);
                }
                if(res.key){
                    XT.tools.setStorage('appKey', res.key);
                }
                if(res.imToken){
                    XT.tools.setStorage('imToken', res.imToken);
                }
                if(res.token){
                    XT.tools.setStorage('token', res.token);
                }
                if(res.imId){
                    XT.tools.setStorage('imAccountId', res.imId);
                }
                if(res.openId){
                    XT.tools.setStorage('openId', res.openId);
                }
                
                XT.tools.setStorage('wxdata', JSON.stringify(res));

                if(options && options.success){
                    options.success(res);
                }
                cb && cb(res);
            };

            XT.jsonp(_wxconfig);
        }
    }else{
        cb && cb(data);
    }
};


// XT init
$(function () {
    if(XT.search.userId) {
        XT.user.id = XT.search.userId;
    }

    if(window.template) {
        template.helper("replaceImg",function  (url,w,h) {
            return XT.getImgUrl(url,w,h);
        })
    }

    if(XT.search.extCode) {
        XT.setShare();
    }
})